【PHP】foreach文 - 反復処理 / 配列の値を1つずつ取り出す繰り返し処理
配列から値を1つずつ取り出すにはforeach文が便利です。
ここではforeach文について解説します。
検証環境
foreach文
foreach文は配列から値を1つずつ取り出す反復処理の構文です。
for文で配列の値を取り出す方法もありますが、foreach文を使うことで、正確に配列のサイズだけ処理を繰り返すことができます。
そのため、コードの可読性向上や不具合の原因を抑える効果を生み出します。
基本構文
foreach( 配列 as 変数 ) {
処理
}
配列
、変数
、処理
の項目は目的のプログラムに合わせて記述します。
各項目の内容は次の通りです。
項目 | 内容 |
---|---|
配列 | 値を取り出す配列 |
変数 | 配列から取り出した値を記憶する変数 |
処理 | 配列の値を取り出すごとに繰り返す処理 |
処理の流れ
foreach文の処理の流れを以下に示します。
- 配列から値を1つ取得する
- 取り出す値がない場合、終了する。
- 取得した値を変数に代入する。
- ブロック(波括弧
{}
)の処理を実行する。 - 1に戻る。
サンプル
<?php
$fruits = [
'Apple',
'Orange',
'Grape',
'Melon',
];
___ih_hl_start
foreach( $fruits as $fruit ) {
echo $fruit."\n";
}
___ih_hl_end
?>
$ php sample1.php
Apple
Orange
Grape
Melon
foreach文の繰り返しごとに$fruits
から値を1つずつ取り出し、as
に続く$$fruit
に記憶しています。
実行結果からも値が1つずつ取り出せていることが分かります。
foreach文とfor文の比較
foreach文ができることは、for文でもできますが、配列から値を取り出す反復処理の場合は、foreach文の方がコードの可読性と不具合の原因を抑える面で優れています。
例えば、上記sample1.phpをfor文で書き換えると次のようになります。
<?php
$fruits = [
'Apple',
'Orange',
'Grape',
'Melon',
];
___ih_hl_start
for( $i = 0; $i < count($fruits); $i++ ) {
echo $fruits[$i]."\n";
}
___ih_hl_end
?>
$ php sample2.php
Apple
Orange
Grape
Melon
for文の場合、条件式や条件式に使用する変数を制御する必要があります。
その分のコードが増えるということは、コードの可読性低下と不具合の原因を誘因します。
もし、条件式を誤って$i <= count($fruits)
としてしまった場合を見てみましょう。
<?php
$fruits = [
'Apple',
'Orange',
'Grape',
'Melon',
];
for( $i = 0; $i <= count($fruits); $i++ ) {
echo $fruits[$i]."\n";
}
?>
$ php sample3.php
Apple
Orange
Grape
Melon
PHP Warning: Undefined array key 4 in sample.php on line 11
Warning: Undefined array key 4 in sample.php on line 11
条件式により$i
が0
〜4
の間は繰り返し処理しますが、4
のキーは存在しないため、エラーが発生します。
foreach文であれば配列のサイズだけ処理を繰り返すので、このような人為的ミスを防ぐことができます。
演習問題
次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。
- 配列型の変数
$price_list
を使用する $price_list
に1000
、2700
、5800
を記憶する$price_list
の値の合計値をforeach文を使って計算する- 合計値は
$total
に記憶する $total
を出力する
9500
コマンドライン引数で与えた数値(複数)の合計値を計算するプログラムを作成してください。
なお、下記条件を満たすものとします。
- 合計値はforeach文を使って計算する
- 合計値は
$total
に記憶する $total
を出力する
$ php practice.php 5 14 28 71
total : 118
$ php practice.php 11 22 33 44 55 66 77 88 99
total : 495